package apuntes;

import java.util.LinkedHashSet;
import java.util.Set;

import aima.core.agent.Action;
import aima.core.agent.impl.DynamicAction;
import aima.core.search.framework.ActionsFunction;
import aima.core.search.framework.ResultFunction;

public class EstadoMisioneros {

	private int numMisioneros; // numMisioneros en orilla izquierda
	private int numCanibales; // numCAnibales en orilla izquierda
	private boolean barcaIzq; // true si barca en orilla izquierda
	
	public static Action M = new DynamicAction("M");
	public static Action MM = new DynamicAction("MM");
	public static Action C = new DynamicAction("C");
	public static Action CC = new DynamicAction("CC");
	public static Action MC = new DynamicAction("MC");
	
		
		public EstadoMisioneros() {
			this(3, 3, true);
			}
			public EstadoMisioneros(EstadoMisioneros mc) {
			this(mc.getnMisioneros(), mc.getnCanibales(), mc.isBarcaIzq());
			}
			public EstadoMisioneros(int nMisioneros, int nCanibales, boolean
			barcaIzq) {
			this.numMisioneros = nMisioneros;
			this.numCanibales = nCanibales;
			this.barcaIzq = barcaIzq;
	}
			
	public int getnMisioneros(){
		return numMisioneros;
	}
	
	public int getnCanibales(){
		return numCanibales;
	}
	
	public boolean isBarcaIzq(){
		return barcaIzq;
	}
	/********************************************************/

	public void moveM() {
		if (barcaIzq)
		numMisioneros--;
		else
		numMisioneros++;
		cambiarDeOrilla();
		}
	
	public void cambiarDeOrilla(){
		barcaIzq = !barcaIzq;
	}
	
	public boolean movimientoValido(Action where) {
		boolean valido = false;
		if (where.equals(M)) {
			if ((barcaIzq && numMisioneros > 0) || (!barcaIzq && numMisioneros < 3)) {
				EstadoMisioneros estadoSiguiente = new EstadoMisioneros(this);
				estadoSiguiente.move(M);
				valido = !estadoSiguiente.peligro();
			}
			else valido = false;
		}
		else if (where.equals(MM)) {
			return valido;
		}
	}
	
	private boolean peligro() {
		if (((numMisioneros < numCanibales) && (numMisioneros != 0))
		|| ((numMisioneros > numCanibales) && (numMisioneros != 3)))
		return true;
		else
		return false;
		}
	
	public boolean equals(Object o) {
		if (this == o) {
		return true;
		}
		if ((o == null) || (this.getClass() != o.getClass())) {
		return false;
		}
		EstadoMisioneros otroEstado = (EstadoMisioneros) o;
		if ((this.numMisioneros == otroEstado.getnMisioneros()) &&
		(this.numCanibales == otroEstado.getnCanibales()) &&
		(this.barcaIzq == otroEstado.isBarcaIzq()))
		return true;
		else
		return false;
		}
		public int hashCode() {
		return (100 * numMisioneros) + (10 * numCanibales) + (barcaIzq ? 1 : 0);
		}

}
